var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/******************************************* */
// 类型断言
// 类型断言就是手动指定一个值的类型，一般用于可能会有多种类型的选择的时候
// 使用方式：值 as 类型，或者<类型>值。为了考虑兼容性，建议使用as来做类型断言
// 联合类型中使用类型断言
function fun1(x) {
    console.log(x.split('').reverse().join());
}
// 使用类型断言需要注意：类型断言只能解决编译时的报错，但是无法避免运行时的报错。合理使用断言，避免断言后调用方法或者深层次引用属性，减少不必要的运行时错误
// 将一个父类断言为更加具体的子类
// 当类之间存在继承关系时，可以使用类型断言
var AError = /** @class */ (function (_super) {
    __extends(AError, _super);
    function AError() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.code = 999;
        return _this;
    }
    return AError;
}(Error));
var BError = /** @class */ (function (_super) {
    __extends(BError, _super);
    function BError() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.status = 200;
        return _this;
    }
    return BError;
}(Error));
// function isAError(error: Error) {
//   if (error instanceof AError) {
//     return true;
//   }
//   return false;
// } // 更推荐
function isAError(error) {
    if (typeof error.code === 'number') {
        return true;
    }
    return false;
}
function isAError2(error) {
    if (typeof error.code === 'number') {
        return true;
    }
    return false;
}
// 将任何一个类型断言为any
// any表示任意类型，一旦某个值的类型被断言为any，那么将可以访问任何属性和方法
// 尽管如此，若非必要，不建议将类型断言为any
window.foo = 1;
// 将任意类型any断言为一个具体的类型
// 遇到any类型时，我们可以将其断言为具体的类型，如果不处理的话，整个代码中将蔓延any
function getCacheData(key) {
    return window.cache[key];
}
var tom = getCacheData('tom');
tom.run();
function testCat(cat) {
    return cat.swim();
} // 双重断言很容易出现运行时错误，若非必要，不建议使用双重断言
// 类型断言与类型转换的区别
// 类型断言只会影响ts编译时的类型，不会实际改变变量的类型，类型断言语句在编译结果中会被删除
// 类型转换会实际改变变量累心
function toBoolean(s) {
    return s; // 原值返回
    // return Boolean(s); // 返回bool值
}
toBoolean(1);
var animal = {
    name: 'tom'
};
// let cat: Cat = animal; // 编译出错
var cat = animal; // 断言，编译正常
// 类型断言和泛型的区别
// 我们可以把函数改造为泛型，在实际调用时指定具体的类型，这样不经可以时间断言一样的效果，而且还可以避免出现any
function getCache(key) {
    return window.cache[key];
}
var catData = getCache('tom');
